﻿using System;
using SecurityTokenServiceNS;
using System.Xml.Linq;
using System.IO;
using System.Xml;
using System.ServiceModel.Security;
using System.ServiceModel.Channels;

namespace RstrModules
{
	public class RSTRModule0502 : IRSTRProcessor
	{
		string _wst = Constants.WSTrust.NamespaceUri0502.ToString();
		WSSecurityTokenSerializer _ser = new WSSecurityTokenSerializer();

		public void ProcessRstr(RSTR rstr, ref XDocument xRstr)
		{
			if (rstr.RST.NamespaceUri != Constants.WSTrust.NamespaceUri0502)
				return;

			MemoryStream ms = new System.IO.MemoryStream();
			XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(XmlWriter.Create(ms));
			EncryptedWSSecurityTokenSerializer eser = new EncryptedWSSecurityTokenSerializer(rstr.RST);

			// <wst:RequestSecurityTokenResponse>
			writer.WriteStartElement("wst", Constants.WSTrust.Elements.RequestSecurityTokenResponse, _wst);

			if (rstr.RST.TokenType != null && rstr.RST.TokenType.Length > 0)
			{   // <wst:TokenType>                
				writer.WriteStartElement("wst", Constants.WSTrust.Elements.TokenType, _wst);
				writer.WriteString(rstr.RST.TokenType);
				writer.WriteEndElement();
			}   // </wst:TokenType>

			if (rstr.RequestedSecurityToken != null)
			{   // <wst:RequestedSecurityToken>             
				writer.WriteStartElement("wst", Constants.WSTrust.Elements.RequestedSecurityToken, _wst);
				eser.WriteToken(writer, rstr.RequestedSecurityToken);
				writer.WriteEndElement();
			}   // </wst:RequestedSecurityToken>

			if (rstr.RequestedAttachedReference != null)
			{   // <wst:RequestedAttachedReference>
				writer.WriteStartElement("wst", Constants.WSTrust.Elements.RequestedAttachedReference, _wst);
				_ser.WriteKeyIdentifierClause(writer, rstr.RequestedAttachedReference);
				writer.WriteEndElement();
			}   // </wst:RequestedAttachedReference>

			if (rstr.RequestedUnattachedReference != null)
			{   // <wst:RequestedUnattachedReference>
				writer.WriteStartElement("wst", Constants.WSTrust.Elements.RequestedUnattachedReference, _wst);
				_ser.WriteKeyIdentifierClause(writer, rstr.RequestedUnattachedReference);
				writer.WriteEndElement();
			}   // </wst:RequestedAttachedReference>

			if (rstr.RST.AppliesTo != null)
			{   // <wsp:AppliesTo>
				writer.WriteStartElement("wsp", Constants.WSPolicy.Elements.AppliesTo, Constants.WSPolicy.NamespaceUri);
				rstr.RST.AppliesTo.WriteTo(AddressingVersion.WSAddressing10, writer);
				writer.WriteEndElement();
			}   // </wsp:AppliesTo>

			if (rstr.RequestedProofToken != null)
			{   // <wst:RequestedProofToken>
				writer.WriteStartElement("wst", Constants.WSTrust.Elements.RequestedProofToken, _wst);
				_ser.WriteToken(writer, rstr.RequestedProofToken);
				writer.WriteEndElement();
			}   // </wst:RequestedSecurityToken>

			if (rstr.Entropy != null && rstr.ComputedKey)
			{
				writer.WriteStartElement("wst", Constants.WSTrust.Elements.RequestedProofToken, _wst);		// <wst:RequestedProofToken>
				writer.WriteStartElement("wst", Constants.WSTrust.Elements.ComputedKey, _wst);				// <wst:ComputeKey>
				if (_wst == Constants.WSTrust.NamespaceUri13)
					writer.WriteValue(Constants.WSTrust.ComputedKeyAlgorithms13.PSHA1);
				else
					writer.WriteValue(Constants.WSTrust.ComputedKeyAlgorithms0502.PSHA1);
				writer.WriteEndElement();																	// </wst:ComputedKey>
				writer.WriteEndElement();																	// </wst:RequestedSecurityToken>

				writer.WriteStartElement("wst", Constants.WSTrust.Elements.Entropy, _wst);					// <wst:Entropy>
				_ser.WriteToken(writer, rstr.Entropy);
				writer.WriteEndElement();																	// </wst:Entropy>
			}

			// </wst:RequestSecurityTokenResponse>
			writer.WriteEndElement();

			writer.Flush();
			ms.Position = 0;
			XmlReader xr = XmlReader.Create(ms);

			xRstr = XDocument.Load(xr);

		}
	}
}
